/**
 * 
 * AxLib - JsBox
 * 
 * Author: WaveF
 * QQ: 298010937
 * 
 * TODO:
 * v2.0.0
 * - [x] Initialize
 * 
 **/

 (function(){

  let axlibPath = getDeploy({ gval: 'AxLib', defaultUrl: 'https://ax.minicg.com/axlib-v3.min.js' });
  let axloaderPath = getDeploy({ gval: 'AxLoader', defaultUrl: 'https://ax.minicg.com/axyepnope.min.js' });

  main();

  function main() {
      if (window.AxJsBox) return;
      window.AxJsBox = { name: 'axjsbox', version: '1.0.0', elements: [] };

      if (!window.yepnope) {
        getAxLoader(inited);
      } else {
        inited();
      }
  }

  function inited() {
    let jsboxs = $('.ax-jsbox');
    $.each(jsboxs, (idx, item) => {
      let codeBox = $(item).find('textarea');
      let rep = $(item).parent().parent();
      let repId = rep.attr('id');
      let repData = $axure(`#${repId}`).getRepeaterData({format:'col'});
      let viewId = codeBox.attr('id').split('_')[0] + '_div';
      let view = $(`#${viewId}`);
      let js = formatCode(codeBox.val());
      let files = repData.files || [];
      files.pop();
      files = files.filter(item=>item!='none'&&item!='');
      let stringFiles = `["${files.join('\",\"')}"]`;
      
      codeBox.hide();
      addLoadingSvg(view);

      let formatInlineFunction = function (func) {
        return func.toString().replace(/VIEW_ID/g, viewId).replace(/REP_ID/g, repId).replace(/  /g, '').trim();
      }

      let showView = function (alpha, pointerEvents) {
        alpha = alpha || 1;
        pointerEvents = pointerEvents || true;
        $('#VIEW_ID').show().css({
          'opacity': alpha,
          'pointer-events': pointerEvents ? 'auto' : 'none'
        });
      }

      let hideView = function () {
        $('#VIEW_ID').hide();
      }

      let setViewStyle = function(css) {
        css = css == 'none' ? { 'border': 'none', 'background-color': 'transparent' } : css;
        $('#VIEW_ID').css(css);
      }

      let showLoading = function () {
        setTimeout(()=>{ $('#VIEW_ID').children('.ax-loading').show(); }, 0);
      }

      let hideLoading = function () {
        setTimeout(()=>{ $('#VIEW_ID').children('.ax-loading').fadeOut(); }, 0);
      }

      let appendHTML = function (str, target) {
        target = target || $('#VIEW_ID');
        target.append(str);
      }

      let appendCSS = function (str) {
        $('head').append('<style>' + str + '</style>');
      }

      let getData = function (format) {
        return $axure('#REP_ID').getRepeaterData(format);
      }
      
      let injectCode = `;let THIS = {
        files: ${stringFiles},
        view: $axure('#${viewId}'),
        repeater: $axure('#${repId}'),
        getData: ${formatInlineFunction(getData)},
        appendHTML: ${formatInlineFunction(appendHTML)},
        appendCSS: ${formatInlineFunction(appendCSS)},
        showView: ${formatInlineFunction(showView)},
        hideView: ${formatInlineFunction(hideView)},
        setViewStyle: ${formatInlineFunction(setViewStyle)},
        showLoading: ${formatInlineFunction(showLoading)},
        hideLoading: ${formatInlineFunction(hideLoading)},
      };`;
      injectCode = injectCode.replace(/  /g, '').replace(/\n/g, '');
      injectCode = '/* inject begin */\n' + injectCode + '\n/* inject end */\n\n';
      js = injectCode + js;
      js = `(function(){\n${js}\n}());`;
      
      if (files.length === 0) {
        finalAppend(view, js);
      } else {
        yepnope({
          load: files,
          complete: ()=>{
            finalAppend(view, js);
          }
        });
      }
    });
  }

  function finalAppend(container, js) {
    container.append(`<script type="text/javascript">${js}</script>`);
    container.find('.ax-loading').hide();
  }

  function getAxLoader(callback) {
    $.getScript(axloaderPath, ()=>{
      yepnope({
        test: window.axlib,
        nope: axlibPath,
        complete: callback
      });
    });
  }

  function getHostPath() {
      let path = window.location.href;
      let arr = path.split('/');
      arr.pop();
      path = arr.join('/');
      return path;
  }

  function getDeploy(params) {
      let { gval, defaultUrl } = params;
      let deploy = '';
      $axure.internal($ax=>{deploy=$ax.globalVariableProvider.getVariableValue(gval)});
      if (deploy === '') { deploy = defaultUrl; }
      if (deploy.indexOf('{host}')>-1) { deploy = deploy.replace('{host}', getHostPath()); }
      return deploy;
  }

  function formatCode(code) {
      return code.replace(/ /gi, '');
  }
  
  function addLoadingSvg(target, options) {
      options = options || { color:'#D1D5DB', opacity:0.2, scale:1.2, delay:0, dur:1, blending:'difference' };

      let svg = `
        <svg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 38 38" stroke="${options.color}" style="transform:scale(${options.scale});">
          <g fill="none" fill-rule="evenodd">
            <g transform="translate(1 1)" stroke-width="2">
              <circle stroke-opacity="${options.opacity}" cx="18" cy="18" r="18"/>
              <path d="M36 18c0-9.94-8.06-18-18-18">
                <animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="${options.dur}s" repeatCount="indefinite"/>
              </path>
            </g>
          </g>
        </svg>
      `;

      $('head').append(`
        <style>
          html, body { height: 100%; }
          .ax-loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: transparent; z-index: 9999; mix-blend-mode:${options.blending}; pointer-events:none; }
          .ax-loading-svg { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
        </style>
      `);
      $(target).append(`<div class="ax-loading"><div class="ax-loading-svg">${svg}</div></div>`);

      return svg;
  }

}());